import smtplib
import imaplib
import email
from email.mime.text import MIMEText
from email.header import Header
from email.header import decode_header  # 显式导入decode_header
import time
import configparser
import os
from sys import exit
import logging
import re
import threading
# 添加json模块用于存储额外的邮件信息
import json
# 添加datetime模块用于时间处理
from datetime import datetime
# 添加email.utils模块用于解析邮件日期
from email.utils import parsedate_to_datetime
# 导入统一的日志模块
from backend.utils.logger import write_log

# 移除旧的日志文件路径定义和write_log函数定义
# LOG_FILE = "system_logs.json"

logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s - %(levelname)s - %(message)s",
    filename="autoemail.log"
)

# 添加全局停止事件
stop_event = threading.Event()

# 添加全局回调函数变量
email_service_callback = None

# ====================== 加载配置文件 ======================
def load_config():
    """
    加载配置文件中的敏感信息
    :return: 配置字典
    """
    config = configparser.ConfigParser()
    # 获取项目根目录路径
    project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
    config_path = os.path.join(project_root, "config.ini")
    
    if not os.path.exists(config_path):
        raise FileNotFoundError("配置文件 config.ini 未找到，请检查路径。")
    
    # 使用utf-8编码读取配置文件
    config.read(config_path, encoding='utf-8')
    return {
        "SMTP_SERVER": config.get("email", "smtp_server"),
        "SMTP_PORT": config.getint("email", "smtp_port"),
        "IMAP_SERVER": config.get("email", "imap_server"),
        "IMAP_PORT": config.getint("email", "imap_port"),
        "SENDER_EMAIL": config.get("email", "sender_email"),
        "SENDER_PASSWORD": config.get("email", "sender_password"),
    }

# 加载配置
try:
    CONFIG = load_config()
    write_log("INFO", "配置文件加载成功")
except Exception as e:
    error_msg = f"加载配置文件时出错: {e}"
    write_log("ERROR", error_msg)
    print(error_msg)
    exit(1)

# ====================== 业务配置 ======================
# 授权关键字列表（用于匹配邮件标题或正文）
AUTHORIZATION_KEYWORDS = ["授权"]
# 需要处理的厂家邮箱列表（仅回复这些发件人的邮件）
AUTHORIZED_VENDORS = ["authcenter@huawei.com",
                      "netcarereport@huawei.com", 
                      "shenzhiqiang8@huawei-partners.com", 
                      "liu.wei101@zte.com.cn", 
                      "zhu.junqiang1@zte.com.cn", 
                      "shao.bin2@zte.com.cn", 
                      "li.fei30@zte.com.cn", 
                      "feng.qinhao@zte.com.cn", 
                      "wang.kun22@zte.com.cn", 
                      "yang.zhentao@zte.com.cn",
                      "chenle@xfusion.com", 
                      "zhangguoxuan@xfusion-partner.com", 
                      "SP.zhuhuanping@h3c.com",
                      "min-feng.lei@h3c.com",
                      "bai.xin@h3c.com", 
                      "gaoqiang@ieisystem-service.com", 
                      "sunjielong@onlinebj.com",
                      "zhu.hp@scsloan.net",
                      "yuxin49@huawei-partners.com", 
                      "liyu102@huawei.com", 
                      "zhaoshanghao@huawei.com",
                      "liuzihui7@huawei-partners.com",
                      "wangzuowei2@huawei-partners.com", 
                      "heyongding1@huawei-partners.com",
                      "zhangzihao17@huawei-partners.com",
                      "huangqiaotong@huawei.com" 
                      ]
# 预先设置的抄送人名单（仅允许这些抄送人）
CC_WHITELIST = ["zhangzihao17@huawei-partners.com", 
                "yuxin49@huawei-partners.com", 
                "liyu102@huawei.com", 
                "liuzihui7@huawei-partners.com", 
                "shenzhiqiang8@huawei-partners.com", 
                "wangtao525@huawei-partners.com", 
                "zhaoshanghao@huawei.com", 
                "huangqiaotong@huawei.com", 
                "wangzuowei2@huawei-partners.com", 
                "heyongding1@huawei-partners.com",
                "gaodong14@huawei-partners.com",
                "sxlibo@sn.chinamobile.com"
                ]

# 在文件开头添加全局变量
PROCESSED_EMAILS_FILE = "processed_emails.txt"

def load_processed_emails():
    """加载已处理的邮件 Message-ID"""
    if not os.path.exists(PROCESSED_EMAILS_FILE):
        return set()
    with open(PROCESSED_EMAILS_FILE, "r", encoding="utf-8") as f:
        return set(line.strip() for line in f if line.strip())

def set_email_service_callback(callback):
    """设置邮件服务回调函数"""
    global email_service_callback
    email_service_callback = callback

def save_processed_email(message_id, sender=None, subject=None, email_date=None, status="processed"):
    """保存已处理的邮件 Message-ID 和详细信息"""
    # 确保message_id不为空
    if not message_id:
        return
        
    # 保存Message-ID到文本文件
    with open(PROCESSED_EMAILS_FILE, "a", encoding="utf-8") as f:
        f.write(message_id + "\n")
    
    # 如果设置了回调函数，则调用它
    if email_service_callback:
        email_service_callback(message_id, sender, subject, email_date, status)
    
    write_log("DEBUG", f"保存邮件信息: {message_id}, 状态: {status}")

# ====================== 功能函数 ======================
def extract_email(full_email):
    """
    从带名称的邮箱字符串中提取纯邮箱地址（如 "Name <email@example.com>" → "email@example.com"）
    """
    if not full_email:
        return ""
    match = re.search(r'<(.+?)>', full_email)
    return match.group(1) if match else full_email

def is_authorization_email(subject, body, from_email, cc_emails=None):
    """
    判断是否为需要回复的授权邮件
    :param cc_emails: 可以是列表或逗号分隔的字符串（如 "a@x.com, b@y.com"）
    """
    if cc_emails is None:
        cc_emails = []

    # 检查标题是否包含"回复"（不区分大小写）
    subject_lower = subject.lower()
    if "回复" in subject_lower:
        # print(f"Debug - 邮件标题包含'回复'，跳过处理: {subject}")
        return False

    # 提取发件人纯邮箱地址
    from_email_clean = extract_email(from_email)
    # print(f"Debug - 发件人原始: {from_email}, 提取后: {from_email_clean}")

    # 清理抄送人列表
    cc_emails_clean = []
    for email in cc_emails:
        if isinstance(email, str):
            cleaned = extract_email(email.strip('"'))
            # 检查清理后的邮箱地址是否有效:
            # 1. cleaned 不为空
            # 2. 包含"@"符号（基本邮箱格式验证）
            if cleaned and "@" in cleaned:
                # 将有效的邮箱地址添加到清理后的抄送人列表
                cc_emails_clean.append(cleaned)
    # 记录调试信息：打印最终清理后的抄送人列表
    # logging.debug(f"抄送人: {cc_emails_clean}")

    # 调试：打印清理后的 cc_emails_clean
    # print(f"Debug - cc_emails_clean: {cc_emails_clean}, type: {type(cc_emails_clean)}")

    # 检查是否包含目标邮箱
    target_email = "sxlibo@sn.chinamobile.com"
    if target_email in cc_emails_clean:
        # print(f"Debug - 跳过邮件，因抄送人包含: {target_email}")
        return False

    # 其余逻辑（发件人检查、关键字检查等）
    # 检查发件人是否为授权厂家邮箱（使用提取后的纯邮箱）
    if from_email_clean not in AUTHORIZED_VENDORS:
        # print(f"Debug - 发件人 {from_email_clean} 不在授权列表中")
        return False
    
    # 检查发件人是否为华为授权中心且邮件有抄送人
    if (from_email_clean == "authcenter@huawei.com" or from_email_clean == "netcarereport@huawei.com") and cc_emails:
        # 验证至少有一人的邮箱在抄送人列表里
        if any(email in CC_WHITELIST for email in cc_emails_clean):
            return True

    # 检查标题或内容是否包含授权关键字"授权"
    subject_lower = subject.lower()
    
    # 如果授权关键字列表为空，直接返回False
    if not AUTHORIZATION_KEYWORDS:
        return False
        
    # 遍历授权关键词列表中的每个关键词
    for keyword in AUTHORIZATION_KEYWORDS:
        # 检查当前关键词是否出现在邮件标题中（不区分大小写）
        # 确保使用正确的编码处理中文字符
        if isinstance(keyword, str) and keyword in subject:
            return True  # 如果找到匹配的关键词，立即返回True
    return False  # 如果遍历完所有关键词都没有匹配，返回False

def send_reply_email(subject, to_email, original_body, original_headers, cc_emails=None):
    """
    发送自动回复邮件，并包含原邮件信息和签名
    """
    # 回复主题直接使用解码后的原主题（不再编码）
    reply_subject = "Re: " + original_headers["Subject"]  # 直接使用已解码的主题

    # 构建回复内容
    reply_body = (
        "同意\n\n"
        "---------------------------------\n"
        "sxlibo@sn.chinamobile.com\n"
        "陕西移动网管中心云平台维护室 李波\n"
        "13571822791\n\n"
        "---------- 原邮件信息 ----------\n"
        f"发件人: {original_headers.get('From', '')}\n"
        f"发送时间: {original_headers.get('Date', '')}\n"
        f"收件人: {original_headers.get('To', '')}\n"
    )
    
    # 添加抄送信息（如果有）
    if original_headers.get('Cc'):
        reply_body += f"抄送: {original_headers.get('Cc', '')}\n"
    
    # 添加原邮件主题和正文
    reply_body += (
        f"主题: {original_headers.get('Subject', '')}\n\n"
        "---------- 原邮件内容 ----------\n"
        "> " + original_body.replace("\n", "\n> ")
    )

    # 构建邮件消息
    msg = MIMEText(reply_body, "plain", "utf-8")
    msg["Subject"] = Header(reply_subject, "utf-8").encode()  # 修复：添加.encode()方法
    msg["From"] = CONFIG["SENDER_EMAIL"]
    msg["To"] = to_email
    if cc_emails:
        msg["Cc"] = "; ".join(cc_emails)

    # 发送邮件
    try:
        with smtplib.SMTP_SSL(CONFIG["SMTP_SERVER"], CONFIG["SMTP_PORT"]) as server:
            server.login(CONFIG["SENDER_EMAIL"], CONFIG["SENDER_PASSWORD"])
            server.sendmail(CONFIG["SENDER_EMAIL"], [to_email] + (cc_emails or []), msg.as_string())
        print("自动回复邮件已发送。")
        write_log("INFO", f"自动回复邮件已发送至: {to_email}")
        return True  # 返回成功状态
    except Exception as e:
        error_msg = f"发送邮件时出错: {e}"
        write_log("ERROR", error_msg)
        print(error_msg)
        return False  # 返回失败状态

def process_email(subject, body, from_email, cc_emails=None, original_headers=None, message_id=None):
    """
    处理邮件并决定是否回复
    :param subject: 邮件标题
    :param body: 邮件内容
    :param from_email: 发件人邮箱
    :param cc_emails: 抄送人邮箱列表
    :param original_headers: 原邮件的头信息（字典格式，包含 From/To/Date/Subject/Cc）
    :param message_id: 邮件的Message-ID
    """
    if is_authorization_email(subject, body, from_email, cc_emails or []):
        success = send_reply_email(subject, from_email, body, original_headers or {}, cc_emails)
        # 根据发送结果保存不同的状态
        if message_id:
            email_date = None
            # 从original_headers中提取邮件日期
            date_header = original_headers.get("Date") if original_headers else None
            if date_header:
                try:
                    email_date = parsedate_to_datetime(date_header).isoformat()
                except:
                    email_date = None
            
            status = "sent" if success else "failed"
            save_processed_email(
                message_id, 
                from_email, 
                subject, 
                email_date,
                status
            )
            write_log("INFO", f"处理授权邮件: {subject}, 状态: {status}")
    else:
        print("非授权邮件，忽略。")
        write_log("DEBUG", f"忽略非授权邮件: {subject}")
        # 保存被忽略的邮件
        if message_id:
            email_date = None
            # 从original_headers中提取邮件日期
            date_header = original_headers.get("Date") if original_headers else None
            if date_header:
                try:
                    email_date = parsedate_to_datetime(date_header).isoformat()
                except:
                    email_date = None
            
            save_processed_email(
                message_id, 
                from_email, 
                subject, 
                email_date,
                "ignored"
            )

def fetch_emails(mail):
    """
    处理新邮件
    :param mail: 已建立的IMAP连接对象
    """
    processed_emails = load_processed_emails()
    try:
        mail.select("inbox")
        status, messages = mail.search(None, "UNSEEN")
        if status != "OK":
            print("未找到新邮件。")
            write_log("INFO", "未找到新邮件")
            return

        email_count = 0
        for num in messages[0].split():
            status, data = mail.fetch(num, "(RFC822)")
            if status != "OK":
                continue

            msg = email.message_from_bytes(data[0][1])
            message_id = msg.get("Message-ID", "").strip()
            if message_id in processed_emails:
                print(f"邮件已处理，跳过 - Message-ID: {message_id}")
                write_log("DEBUG", f"邮件已处理，跳过 - Message-ID: {message_id}")
                continue

            # 解码主题（处理多段MIME编码）
            subject = ""
            for part, encoding in decode_header(msg.get("Subject", "")):  # 修复：使用显式导入的decode_header
                if isinstance(part, bytes):
                    subject += part.decode(encoding if encoding else "utf-8")
                else:
                    subject += part

            # 提取其他头信息（From/To/Date等）
            original_headers = {
                "From": msg.get("From", ""),
                "Date": msg.get("Date", ""),
                "To": msg.get("To", ""),
                "Subject": subject,  # 使用解码后的主题
                "Cc": msg.get("Cc", ""),
            }

            # 提取发件人邮箱（从 "Name <email>" 中提取纯邮箱）
            from_header = msg.get("From", "")
            if "<" in from_header and ">" in from_header:
                from_email = from_header.split("<")[-1].split(">")[0].strip()
            else:
                from_email = from_header.strip()

            cc_emails = []
            cc_header = msg.get("Cc")
            if cc_header:  # 修复：检查cc_header是否为None
                cc_emails = [email.strip() for email in cc_header.split(",")]
            
            # 解析邮件正文
            body = ""
            if msg.is_multipart():
                for part in msg.walk():
                    if part.get_content_type() == "text/plain":
                        payload = part.get_payload(decode=True)
                        if isinstance(payload, bytes):  # 修复：检查payload是否为bytes
                            body = payload.decode("utf-8", errors="ignore")
                        else:
                            body = str(payload)
                        break
            else:
                payload = msg.get_payload(decode=True)
                if isinstance(payload, bytes):  # 修复：检查payload是否为bytes
                    body = payload.decode("utf-8", errors="ignore")
                else:
                    body = str(payload)

            # 打印调试信息（解码后的标题和纯邮箱）
            # print(f"收到新邮件 - 标题: {subject}, 发件人: {from_email}")
            # print(f"邮件正文: {body[:100]}...")

            # 处理邮件并传递 original_headers
            process_email(subject, body, from_email, cc_emails, original_headers, message_id)
            email_count += 1
            # 原来的save_processed_email调用已移至process_email中

        write_log("INFO", f"本次检查处理了 {email_count} 封新邮件")
    except imaplib.IMAP4.error as e:
        error_msg = f"IMAP协议错误: {e}"
        write_log("ERROR", error_msg)
        print(error_msg)
        raise  # 重新抛出异常，由 monitor_emails 处理
    except Exception as e:
        error_msg = f"处理邮件时出错: {e}"
        write_log("ERROR", error_msg)
        print(error_msg)

def monitor_emails(interval=1800):
    """
    定时监听邮箱
    :param interval: 监听间隔（秒）
    
    注意：在不同的使用场景中，建议使用不同的间隔时间：
    - 独立脚本运行：1800秒（30分钟）
    - Web服务中调用：300秒（5分钟）以获得更好的响应性
    """
    print("开始监听邮箱...")
    write_log("INFO", "开始监听邮箱...")
    mail = None
    try:
        mail = imaplib.IMAP4_SSL(CONFIG["IMAP_SERVER"], CONFIG["IMAP_PORT"])
        mail.login(CONFIG["SENDER_EMAIL"], CONFIG["SENDER_PASSWORD"])
        write_log("INFO", "邮箱登录成功")
        
        while not stop_event.is_set():
            fetch_emails(mail)
            # 等待指定间隔或收到停止信号
            if stop_event.wait(interval):
                break
    except KeyboardInterrupt:
        print("程序已手动终止")
        write_log("INFO", "程序已手动终止")
    except Exception as e:
        error_msg = f"监听邮箱时出错: {e}"
        write_log("ERROR", error_msg)
        print(error_msg)
    finally:
        # 检查mail对象是否存在，如果存在则尝试安全登出邮箱
        if mail:
            try:
                mail.logout()  # 执行IMAP登出操作
                write_log("INFO", "邮箱登出成功")
            except Exception as e:
                # 捕获并打印登出过程中可能发生的任何异常
                error_msg = f"退出邮箱时出错: {e}"
                write_log("ERROR", error_msg)
                print(error_msg)
        print("邮箱监听服务已停止")
        write_log("INFO", "邮箱监听服务已停止")